package com.my.result;

import lombok.Data;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * @author : jhxue
 * @date : 2023/1/5 16:32
 * <p>
 * 统一结构响应体
 */
@Data
public class Result<T> implements Serializable {

    /**
     * 返回码
     */
    private Integer code;

    /**
     * 返回信息
     */
    private String msg;

    /**
     * 返回数据
     */
    private T data;


    protected static <T> Result<T> build(T data) {
        Result<T> result = new Result<>();
        if (data != null) {
            result.setData(data);
        }
        return result;
    }

    public static <T> Result<T> build(T body, Integer code, String msg) {
        Result<T> result = build(body);
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }

    public static <T> Result<T> build(T body, ResultCode resultCode) {
        Result<T> result = build(body);
        result.setCode(resultCode.getCode());
        result.setMsg(resultCode.getMsg());
        return result;
    }

    public static <T> Result<T> ok() {
        return Result.ok(null);
    }

    public static <T> Result<T> ok(T data) {
        Result<T> result = build(data);
        return build(data, ResultCode.SUCCESS);
    }

    public static <T> Result<T> fail() {
        return Result.fail("");
    }

    public static <T> Result<T> fail(String msg) {
        Result result = new Result();
        result.setCode(ResultCode.FAIL.getCode());
        result.setMsg(msg);
        return result;
    }

    public static <T> Result<T> fail(Integer code, String msg) {
        Result result = new Result();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }

    public static <T> Result<T> fail(T data) {
        Result<T> result = build(data);
        return build(data, ResultCode.FAIL);
    }

    public static <T> Result<T> fail(ResultCode resultCode) {
        Result result = new Result();
        result.setCode(resultCode.getCode());
        result.setMsg(resultCode.getMsg());
        return result;
    }

    public Result<T> message(String msg) {
        this.setMsg(msg);
        return this;
    }

    public Result<T> code(Integer code) {
        this.setCode(code);
        return this;
    }

    public Result<T> data(String key, Object value) {
        Map map = new HashMap<>();
        map.put(key, value);
        this.setData((T) map);
        return this;
    }

    public static <T> Result<T> judge(boolean result) {
        if (result) {
            return ok();
        } else {
            return fail();
        }
    }

    public static <T> Result<T> judge(boolean flag, String trueMsg, String falseMsg) {
        Result result = new Result();
        if (flag) {
            result.setCode(ResultCode.SUCCESS.getCode());
            result.setMsg(trueMsg);
        } else {
            result.setCode(ResultCode.FAIL.getCode());
            result.setMsg(falseMsg);
        }
        return result;
    }

    public static <T> Result<T> judge(boolean flag, String trueMsg, String falseMsg, T data) {
        Result result = new Result();
        if (flag) {
            result.setCode(ResultCode.SUCCESS.getCode());
            result.setMsg(trueMsg);
            result.setData(data);
        } else {
            result.setCode(ResultCode.FAIL.getCode());
            result.setMsg(falseMsg);
        }
        return result;
    }


    public static boolean isSuccess(Result<?> result) {
        return result != null && ResultCode.SUCCESS.getCode().equals(result.getCode());
    }

}
